package com.lx.boot1.canal;

import com.alibaba.otter.canal.protocol.CanalEntry;
import com.lx.boot.canal.CanalService;
import com.lx.entity.Var;
import com.lx.util.LX;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CommodityCanalService extends CanalService<Commodity> {
    @Autowired
    private SpringTemplateEngine springTemplateEngine;


    /**  https://www.thymeleaf.org/doc/tutorials/3.1/thymeleafspring.html */
    protected void insert(CanalEntry.RowChange rowChange) throws Exception {
        List<Commodity> commodityList = getAfter(rowChange);
        log.info("新增商品"+commodityList.toString());
        for (Commodity commodity : commodityList) {
            if(LX.isEmpty(commodity.getPicture())){
                continue;
            }
            Context context = new Context();
            context.setVariables(new Var("commodity",commodity));
            String content = springTemplateEngine.process("commodity", context);
            writeToFile(content,getFileName(commodity.getCId()+""));
        }
    }

    private String getFileName(String cId) {
        return "static/commodity/" + cId + ".html";
    }

    private void writeToFile(String content, String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()){
            file.getParentFile().mkdirs();
        }
        log.info("write file:{}",filePath);
        try(FileOutputStream fileOutputStream = new FileOutputStream(file);){
            LX.inputStreamToOutputStream(new ByteArrayInputStream(content.getBytes()),fileOutputStream);
        }catch (Exception e){
            throw e;
        }
    }

    protected void update(CanalEntry.RowChange rowChange) throws IOException {
        deleteUpdateCidFile(rowChange);
        List<Commodity> commodityList = getAfter(rowChange);
        log.info("编辑商品"+commodityList.toString());
        for (Commodity commodity : commodityList) {
            if(LX.isEmpty(commodity.getPicture())){
                continue;
            }
            Context context = new Context();
            context.setVariables(new Var("commodity",commodity));
            String content = springTemplateEngine.process("commodity", context);
            writeToFile(content,getFileName(commodity.getCId()+""));
        }
    }

    private void deleteUpdateCidFile(CanalEntry.RowChange rowChange) {
        rowChange.getRowDatasList().stream().forEach(v->{
            for (CanalEntry.Column column : v.getAfterColumnsList()) {
                if ("c_id".equals(column.getName())){
                    if (column.getUpdated()){
                        File f = new File(getFileName(column.getValue()));
                        log.info("delete file:{}",f.getName());
                        f.delete();
                    }
                    break;
                }
            }
        });
    }

    protected void delete(CanalEntry.RowChange rowChange) {
        List<Commodity> commodityList = getBefore(rowChange);
        log.info("删除商品"+commodityList.toString());
        for (Commodity commodity : commodityList) {
            File f = new File(getFileName(commodity.getCId()+""));
            f.delete();
        }
    }

    public byte[] serialize(Integer integer) {
        return (integer == null ? null : String.valueOf(integer).getBytes(StandardCharsets.UTF_8));
    }

    @Override
    protected String getTableName() {
        return "commodity";
    }

    @Override
    protected void notifiy(String tableName, CanalEntry.EventType eventType, CanalEntry.RowChange rowChange) throws Exception {
        switch (eventType){
            case INSERT -> {
                insert(rowChange);
            }
            case UPDATE -> {
                update(rowChange);
            }
            case DELETE -> {
                delete(rowChange);
            }
        }
    }
}
